.TH ser2net.yaml 5 06/02/01  "Serial to network proxy configuration file"

.SH NAME
/etc/ser2net/ser2net.yaml \- Serial to network proxy configuration file

.SH DESCRIPTION
ser2net used to be a program for connection network connections to
serial ports.  It's now a program for connecting accepter gensio to
connecting gensios.  See gensio(5) for details on gensios.

ser2net is configured with yaml, which is flexible and easy to use.
Look at yaml documentation on the internet for how that works.

.SH DEFINE SPECIFICATION
YAML has the ability to create aliases that can be used elsewhere in
the configuration file.  These can be used for tying things together
between parts of the file, or (as an extension to YAML) for string
subtitution.

You define an alias with the following:
.IP
define: &aliasname alias text
.PP
This will create an alias with the given name.  Then you can use it
elsewhere like:
.IP
banner: *aliasname
.PP
and the banner will be "alias text".  Unlike standard YAML, you can
also use this inside strings using
.IP
*(aliasname)
.PP
so if you have
.IP
banner: My banner *(aliasname) is here
.PP
The banner will be "My banner alias text is here".  See the YAML
documentation for how spaces are handled, but as a note, use quotes if
you are not sure, like:
.IP
define: &aliasname "alias text"
banner: "My banner *(aliasname) is here"
.PP

If you for some reason need "*(" in your text, use "*(*" for that.

.SH USING EXTERNAL FILES
You may want to store passwords and such in external files for better
security.  Putting "*{filename}" in a YAML scalar will put the file's
contents into the scalar at that point.  If you need a "*{" in the
string for some reason, use "*{*".

.SH CONNECTION SPECIFICATION
A connection is a structure that describes how to connect an accepting
gensio to a connecting gensio.

An accepter specification looks like:

.RS
connection: &<alias>
.RS
accepter: <accepter>
.br
timeout: <number>
.br
enable: on|off
.br
connector: <connector>
.br
options:
.RS
<option name>: <option value>
.br
<option name>: <option value>...
.RE
.RE
.RE

An <accepter> is an accepting gensio specification.  When ser2net
receives a connection on the accepter, it attempts to make a connection
to the <connector> gensio.  The alias is required, it sets the name
that is used for the connection in the admin interface and for
referencing from rotators.

If the connection receive no activity in <timeout> seconds, ser2net
will close the connection.  Setting <timeout> to zero disables the
timeout.  The timeout field is optional and defaults to zero.

The connection may be enabled or disabled with the enable.  The enable
field is optional and defaults to on.  This is useful for temporarily
disabling port by setting enable to off and sending a SIGHUP.  If
there are users connected and you disable a port and send a SIGHUP,
the users will be kicked off.

An option is a configuration setting that doesn't have anything to do
with specific gensios, they are controls for ser2net in general.  The
option section is optional.

See gensio(5) for a lot of information about the specific gensios
available.

To allow a TCP connection to a serial port and ignore modem control,
you can do:
.RS
connection: &toS0tcp
.RS
accepter: tcp,1234
.br
connector: serialdev,/dev/ttyS0,local
.RE
.RE
.PP

Both accepting and connecting gensios stack, so if you want to add
telnet with RFC2217 support, you can do:
.RS
connection: &toS0telnet
.RS
accepter: telnet(rfc2217)tcp,1234
.br
connector: serialdev,/dev/ttyS0,local
.RE
.RE

If you want to accept a telnet over SCTP connection only on IPv6
localhost and connect to a telnet connection with SSL over tcp, you
can do:
.RS
connection: &tomyhost
.RS
accepter: telnet,sctp,::1,1234
.br
connector: telnet,ssl,tcp,myhost.domain.org,1234
.RE
.RE

RFC2217 support only make sense with a serial-capable device as the
connector.  Also note that IPv6 is fully supported.  Accepters will
generally default to being both IPv4 and IPv6 unless otherwise
specified.  See gensio(5) for details.

And yes, SCTP is supported and is highly recommended if you can use
it.  Multi-homing alone is worth it.

You could create a secure login with telnet RFC2217 support that then
connects to an IPMI sol connection.  Notice how splitting the connector
line is done with YAML.
.RS
connection: &authsol
.RS
.br
accepter: telnet(rfc2217),mux,certauth,ssl,sctp,1234
.br
connector: ipmisol,lan -U ipmiusr -P test -p 9001
.br
.RS
.RS
ipmiserver.domain.org,9600
.RE
.RE
.br
options:
.RS
banner: My banner
.RE
.RE
.RE

These are some examples.  For SSL and certauth, I have ignored the
authentication configuration, more on that later.  Using
authentication is strongly recommended, it's easy now with gtlssh and
if you need to use it from a program, it's easy with gensio.  There is
even python support.  Adding support for other scripting languages
shouldn't be too hard.

.SS "SPECIAL STRING HANDLING"

Some string values, like banners, have special formatting for
inserting various values.  These are all prepended with '\e'.  This
takes the standard "C" \ex characters.

.RS 2
\ea - bell
.br
\eb - backspace
.br
\ef - form feed
.br
\en - newline
.br
\er - carriage return
.br
\et - tab
.br
\ev - vertical tab
.br
\e\e - \e
.br
\e? - ?
.br
\e' - '
.br
\e" - "
.br
\ennn - octal value for nnn
.br
\exXX - hex value for XX
.br
\ed - The connector string (/dev/ttyS0, etc.)
.br
\eo - The name of the connection.
.br
\ep - Network port number
.br
\eB - The serial port parameters (eg 9600N81) if applicable
.br
\eY -> year
.br
\ey -> day of the year (days since Jan 1)
.br
\eM -> month (Jan, Feb, Mar, etc.)
.br
\em -> month (as a number)
.br
\eA -> day of the week (Mon, Tue, etc.)
.br
\eD -> day of the month
.br
\ee -> epoc (seconds since Jan 1, 1970)
.br
\eU -> microseconds in the current second
.br
\ep -> local port number
.br
\eI -> remote IP address (in dot format)
.br
\eH -> hour (24-hour time)
.br
\eh -> hour (12-hour time)
.br
\ei -> minute
.br
\eS -> second
.br
\eq -> am/pm
.br
\eP -> AM/PM
.RE

These sequences may be used to make the filename unique per open and
identify which port/device the filename was for.  Note that in
filenames when using \ed or \eo, everything up to and including last /
in the device name is removed, because you can't have a / in a
filename.  So in a filename /dev/ttyS0 would become just ttyS0.

Note that in banners and other strings going out (not filenames) you
.B must
use \er\en to send a new line; this is raw handling and \en will only go
down one line, it will not return to the beginning of the line.

.SS "CONNECTION SPECIFICATION OPTIONS"

.I kickolduser: true|false
sets the port so that the previous user will be kicked off if a new user
comes in.  Useful if you forget to log off from someplace else a lot.

.I banner: <banner string>
displays the given banner when a client connects.  It uses string
handling as described in "SPECIAL STRING HANDLING" above.

.I signature: <signature string>
sends RFC2217 signature on clients request.  This may be an empty
string.

.I openstr: <openstr name string>
Send the given string to the device on first open.  This may be an
empty string.  It uses string handling as described in "SPECIAL STRING
HANDLING" above.

.I closestr: <closestr name>
Send the given string to the device on final close.  This may be an
empty string.  It uses string handling as described in "SPECIAL STRING
HANDLING" above.

.I closeon: <closeon string>
If the given string is seen coming from the connector side of the
connection, close the connection.  The comparison here is, for
simplicity, simplistic.  Complex expressions with repetative things
may not compare correctly.  For instance, if your closeon strings is
"ababc" and your input strings is "abababc", the comparison will fail
because the comparison algorithm will see "ababa" and will fail on the
final "a" and start over at "abc", which won't match.  This shouldn't
cause a problem most cases, but if it does, contact the authors and it
can be improved.

.I accepter-retry-time: <time in seconds>
If the accepter does not come up at startup, wait this many seconds
and retry it.

.I connector-retry-time: <time in seconds>
On a connect-back port, if the connector does not come up or goes
down.  wait this many seconds and retry it.

.I trace-read: <filename>
When the acceptor is opened, open the given file and store all data
read from the physical device (and thus written to the client's
network/acceptor port) in the file.  If the file already exists, it is
appended.  The file is closed when the port is closed.  The filename
uses string handling as described in "SPECIAL STRING HANDLING" above.

.I trace-write: <filename>
Like tr, but traces data written to the connecting gensio.

.I trace-both: <filename>
trace both read and written data to the same file.  Note that this is
independent of tr and tw, so you may be tracing read, write, and both
to different files.

.I trace-hexdump: true|false
turns on/off hexdump output to all trace files.  Each line in the
trace file will be 8 (or less) bytes in canonical hex+ASCII format.  This is
useful for debugging a binary protocol.

.I trace-timestamp: true|false
adds/removes a timestamp to all of the trace files. A timestamp
is prepended to each line if hexdump is active for the trace file.  A
timestamped line is also recorded in the trace file when a remote client
connects or disconnects from the port.

.I [trace-read-|trace-write-|trace-both-]hexdump: true|false
turns on/off hexdump output for only one trace file.
May be combined with hexdump.  Order is important.

.I [trace-read-|trace-write-|trace-both-]timestamp: true|false
adds/removes a timestamp to only one the trace files
May be combined with [-]timestamp.  Order is important.

.I telnet-brk-on-sync: true|false
causes a telnet sync operation to send a break.  By default data is
flushed until the data mark, but no break is sent.

.I chardelay: true|false
enables the small wait after each character received on the
connecting gensio before sending data on the accepted gensio.
Normally ser2net will wait the time it takes to receive 2 serial port
characters, or at least 1000us, before sending.  This allows more
efficient use of network resources when receiving large amounts of
data, but gives reasonable interactivity.  Default is true.

.I chardelay-scale: <number>
sets the number of serial port characters, in tenths of a character,
to wait after receiving from the connection gensio and sending to the
accepted gensio.  So setting this to 25 will cause ser2net to wait the
amount of time it takes to recieve 2.5 serial port characters before
sending the data on to the TCP port.  The default value is 20.

.I chardelay-min: <number>
sets the minimum delay that ser2net will wait, in microseconds.  If
the calculation for chardelay-scale results in a value smaller than
this number, this number will be used instead.  The default value
is 1000.

.I chardelay-max: <number>
sets the maximum delay that ser2net will wait, in microseconds, before
sending the data.  The default value is 20000.  This keeps the connection
working smoothly at slow speeds.

.I sendon: <sendon string>
If the given string is seen coming from the connector side of the
connection, sends buffered data up to and including the
string. Disabled by default. As an example, this can be set to \er\en
with appropriate chardelay settings to send one line at a time.  It
uses string handling as described in "SPECIAL STRING HANDLING" above.
See the notes on the closeon string for important information on how
the comparison is done.

.I dev-to-net-bufsize: <number>
sets the size of the buffer reading from the connecting gensio and writing
to the accepted gensio.

.I net-to-dev-bufsize: <number>
sets the size of the buffer reading from the accepted gensio and
writing to the connecting gensio.

.I led-tx: <led-alias>
use the previously defined led to indicate serial tx traffic on this port.
This should be a YAML alias, like *led2.

.I led-rx: <led-alias>
use the previously defined led to indicate serial rx traffic on this port.
This should be a YAML alias, like *led2.

.I max-connections: <number>
set the maximum number of connections that can be made on this particular
TCP port.  If you make more than one connection to the same port, each
ports output goes to the device, and the device output goes to all ports
simultaneously.  See "MULTIPLE CONNECTIONS" below for details.  The default
is 1.

.I remaddr: <addr>[;<addr>[;...]]
specifies the allowed remote connections, where the addr is a standard
address, generally in the form <ip address>,<port>.  Multiple
addresses can be separated by semicolons, and you can specify remaddr
more than once.

If you set the port for an address to zero, ser2net will accept a
connection from any port from the given network host.

.I connback: <connector>[;<connector>[;...]]
specifies reverse connections that will be made when data comes in on
the device.  When data comes in on the device side (the connection's
main connector) ser2net will connect to each connback specified.  No
connection is made until data comes in, and normal connection timeouts
apply.

Note that this will use one of the connection's connections all the
time.  You may need to increase max-connections if you need more than
one or want to accept incoming connections, too.

Connect back addresses must match the format of the accepter address.
So, for instance, if your accepter is "telnet,tcp,1234" your connect
back address must be something like "telnet,tcp,hostname,1123".

The port will send no data to any connect back unless all the connect
backs are connected.

A connect back port can also have connections made to it if you set
the number of connections larger than the number of connect backs
specified.  However, those connections will receive no data from the
port uness all connect backs have been established.

.I authdir: <directory string>
specified the authentication directory to use for this connection.

.I allowed-users: <space separated list of names>
The users that are allowed to use this connections.  This has no
meaning if authentication is not enabled on the connections.  If this
is not set or defaulted, all users are allowed.  If this is set to an
empty set of users, then no users are allowed.  This may be specified
more than once, each one adds more users.

.I mdns: true|false
Enables/disables mdns support for the connection.  If you set this and
mdns is available, ser2net will create a service on mdns for the port.

.I mdns-interface: <num>
Sets the specific network interface to advertise the device.  Defaults
to -1, which means all network interfaces.

.I mdns-nettype: unspec|ipv4|ipv6
Sets which network type to provide for the device advertisement.
Defaults to unspec, which means do ipv4 and ipv6.

.I mdns-name: <string>
Sets the name in the mDNS advertisement.  Defaults to the connection name.

.I mdns-type: <string>
Sets the type in the mDNS advertisement.  Defaults to "_iostream._xxx"
where xxx is either tcp, udp # # or sctp base on the gensio type.

.I mdns-domain: <string>
Sets the name in the mDNS advertisement.  Defaults to the system
setting.  Don't set this unless you really know what you are doing.

.I mdns-host: <string>
Sets the host in the mDNS advertisement.  Defaults to the system
setting.  Don't set this unless you really know what you are doing.

.I mdns-txt: <string>
Adds a text string to the mDNS advertisement.  The string should be in
the form "name=value".  You can put anything you want in the strings.
Two default strings are added by ser2net: "provider=ser2net" and
"gensiostack=..." where the stack of gensios is added, like
"telnet(rfc2217),tcp)".  The idea of gensiostack is you can just tack
on the address to the end an make a connection using str_to_gensio().

.I mdns-sysattrs: true|false
On Linux adds system attributes from sysfs for USB serial ports to the
mDNS txt fields.  If the serial port is USB, it adds
"devicetype=serialusb" and the following attributes from sysfs:
bInterfaceNumber, interface, idProduct, idVendor, serial,
manufacturer, product.  If they are not present in sysfs, they are not
added.  If the serial port is not USB, then "devicetype=serial" is
added.

Note: Be *very* careful when using a gensiostack with str_to_gensio().
Just blindly calling str_to_gensio() with it could result in
significant security issues, as it can pass pty, stdio, trace,
etc. gensios in it.  You must either validate that the stack is a safe
set or just use it for information.  You have been warned.  Be careful.
.SH "ROTATOR"
A rotator allows a single network connection to connect to one of a
number of connections.

A rotator specification looks like:
.RS
rotator: &<alias>
.RS
accepter: <accepter>
.br
connections: [
.RS
<connection alias>,
.br
<connection alias>....
.RE
]
.br
options:
.RS
<option name>: <option val>
.br
<option name>: <option val>...
.RE
.RE
.RE

A rotator has three possible options, "authdir", "allowed-users", and
"accepter-retry-time", both same as connections.

You should use YAML aliases for the connections.

Connections to the accepter will go through the set of connections and
find the first unused one and use that.  The next connection will
start after the last connection used.  Note that disabled connections
are still accessible through rotators.

Note that the security of the connection is
.B NOT
used, only the security of the rotator.

.SH "SER2NET DEFAULTS"
To set a default, do:
.RS
default:
.RS
.br
name: <default name>
.br
value: <default value>
.br
class: <default class>
.RE
.RE

The class is optional, if it is not there it sets the base default for
all classes that is used unelss overridden for a specific class.  If
the class is there, it sets the default for a specific gensio class.
There is also a ser2net class that is for ser2net specific options.

The class is useful if you want different values for different gensio
types.  For instance, if you wanted all serial ports to run at 9600
baud and all IPMI SOL connections to run at 115200 baud, you could do:
.RS
default:
.RS
name: speed
.br
value: 9600
.br
class: serialdev
.RE
default:
.RS
name: speed
.br
value: 115200
.br
class: ipmisol
.RE
.RE

The value is also optional, if it is not present a string value is set
to NULL and an integer value is set to 0.

The order in the file is important, you must set a default before it
is used, and you can change the value of the default.  It will affect
all uses following the setting.

To delete a default value for class (so it will use the base default), do:
.RS
delete_default:
.RS
name: <default name>,
.br
class: <default class>
.RE
.RE

You must supply the class, you cannot delete base defaults.

The following default values are specific to ser2net, given with their
default values:
.TP
.B telnet-brk-on-sync: false
If a telnet sync is received, send a break on the connected gensio (if
applicable).  By default data is flushed until the data mark, but no
break is sent.
.TP
.B kickolduser: false
If a new user comes in on a connection that already has a user, kick
off the previous user.
.TP
.B chardelay: true
Enable asmall wait after each character received on the serial
port before sending data on the TCP port.  Normally ser2net will wait
the time it takes to receive 2 serial port characters, or at least
1000us, before sending on the TCP port.  This allows more efficient
use of network resources when receiving large amounts of data, but
gives reasonable interactivity.
.TP
.B chardelay-scale: 20
sets the number of serial port characters, in tenths of a character,
to wait after receiving from the serial port and sending to the TCP
port.  So setting this to 25 will cause ser2net to wait the amount
of time it takes to recieve 2.5 serial port characters before sending
the data on to the TCP port.  This can range from 1-1000.
.TP
.B chardelay-min: 1000
sets the minimum delay that ser2net will wait, in microseconds.  If
the calculation for chardelay-scale results in a value smaller than
this number, this number will be used instead.  The default value
is 1000.  This can range from 1-100000.
.TP
.B net-to-dev-bufsize: 64
sets the size of the buffer reading from the network port and writing to the
serial device.
.TP
.B dev-to-net-bufsize: 64
sets the size of the buffer reading from the serial device and writing
to the network port.
.TP
.B max-connections: 1
set the maximum number of connections that can be made on this
particular TCP port.  If you make more than one connection to the same
port, each ports output goes to the device, and the device output goes
to all ports simultaneously.  See "MULTIPLE CONNECTIONS" below.
for details.
.TP
.B remaddr: [!]<addr>[;[!]<addr>[;...]]
specifies the allowed remote connections, where the addr is a standard
address in the form (see "network port" above).  Multiple addresses
can be separated by semicolons, and you can specify remaddr more than
once.  If you set the port for an address to zero, ser2net will accept
a connection from any port from the given network host.  If a "!" is
given at the beginning of the address, the address is a "connect back"
address.  If a connect back address is specified, one of the network
connections (see max-connections) is reserved for that address.  If
data comes in on the device, ser2net will attempt to connect to the
address.  This works on TCP and UDP.
.TP
.B authdir: /usr/share/ser2net/auth
The authentication directory for ser2net.  The AUTHENTICATION for more
details.
.TP
.B authdir-admin: /etc/ser2net/auth
The authentication directory for ser2net for admin connections.  The
"ADMIN_CONNECTIONS" for more details.
.TP
.B mdns-interface: -1
The default mDNS interface.
.TP
.B mdns-type: <NULL>
The default mDNS type.
.TP
.B mdns-domain: <NULL>
The default mDNS domain.
.TP
.B mdns-host: <NULL>
The default mDNS host.
.SH ADMIN CONNECTIONS
There is an admin accepter that you can define for ser2net, it lets you
log in, look at status, and change some things.  See "ADMIN INTERFACE"
in ser2net(8) for detail on how to use it.  The format is:
.RS
admin:
.RS
accepter: <accepter>
.br
options:
.RS
<option name>: <option value>
.br
<option name>: <option value>...
.RE
.RE
.RE

The only option available is "authdir-admin", which sets the
authentication directory for the admin port.  This is different than
the authdir for connections and rotators, though you can set it to the
same value.

.SH LEDS
.B ser2net
can flash LEDs during serial activity.  To create an LED, do:
.RS
led: &<alias>
.RS
driver: sysfs
.br
options:
.RS
<option name>: <option value>
.br
<option name>: <option value>
.RE
.RE
.RE

The only supported driver is sysfs.  Supported options are:

.I device: <sysfs device name>
gives the name of the LED in /sys/class/led.  These generally have ":"
in them, so you will need to put the name in quotes.  This is required.

.I duration: <time in ms>
The time in milliseconds to flash the LED.  Defaults to 10.

.I state: <number>
The value to set the LED to to enable it.  Defaults to 1, but may need
to be a different value.

You reference the LED by alias in the connection options section, see
that for details.  Make sure you have "modprobe ledtrig-transient"
done or the triggers will not work, they require the transient trigger.

You also probably need root access to access LED settings.

.SH FILENAME, BANNER, AND STRING FORMATTING
NOTE: yaml has it's own quoting mechanism, see below for more details.

Filenames, banners, open/close strings, closeon strings, and sendon
strings may contain normal "C" escape sequences and a large number of
other escape sequences, too:

.RS 2
\ea - bell
.br
\eb - backspace
.br
\ef - form feed
.br
\en - newline
.br
\er - carriage return
.br
\et - tab
.br
\ev - vertical tab
.br
\e\e - \e
.br
\e? - ?
.br
\e' - '
.br
\e" - "
.br
\ennn - octal value for nnn
.br
\exXX - hex value for XX
.br
\ed - The connecting gensio string (serialdev,/dev/ttyS0, etc.)
.br
\eo - The device as specified on the config line (before DEVICE substitution)
.br
\eN - The port name
.br
\ep - The accepter string
.br
\eB - The serial port parameters (eg 9600N81)
.br
\eY -> year
.br
\ey -> day of the year (days since Jan 1)
.br
\eM -> month (Jan, Feb, Mar, etc.)
.br
\em -> month (as a number)
.br
\eA -> day of the week (Mon, Tue, etc.)
.br
\eD -> day of the month
.br
\ee -> epoc (seconds since Jan 1, 1970)
.br
\eU -> microseconds in the current second
.br
\ep -> local port number
.br
\eI -> remote address of the accepter gensio
.br
\eH -> hour (24-hour time)
.br
\eh -> hour (12-hour time)
.br
\ei -> minute
.br
\eS -> second
.br
\eq -> am/pm
.br
\eP -> AM/PM
.RE

In addition, for backwards compatibility because filenames and banners
used to have different formatting, \es is the serial port parameters
if in a banner and seconds if in a filename.  Use of this is
discouraged as it may change in the future.

These sequences may be used to make the filename unique per open and
identify which port/device the filename was for.  Note that in
filenames when using \ed or \eo, everything up to and including last /
in the device name is removed, because you can't have a / in a
filename.  So in a filename /dev/ttyS0 would become just ttyS0.

.SS HANDLING QUOTING AND STRING FORMATTING
yaml will process "\e" escape sequences in double quotes, so use of
double quotes is note recommended for the above.  If you put the
values in single quotes, yaml will not process them and instead pass
them through where they can be processed by ser2net.

.SH SPACES, QUOTING AND PUTTING SPACES IN STRINGS
YAML and the accepter/connector processing interact when dealing with
quoting.  By default, YAML ignores the number of spaces between
elements separated by spaces.  Lines that are indented after an
element are considered a continuation of the element, so something like:
.RS
connector: serialdev,/dev/ttyUSB0,
.RS
9600n81
.br
local nobreak
.br
rtscts
.RE
.RE
is the same as
.IP
connector: serialdev,/dev/ttyUSB0, 9600n81 local nobreak rtscts
.PP

YAML has it's own standard quoting mechanisms, so if you do:
.IP
connector: "serialdev,/dev/ttyUSB0,9600n81  local"
.PP
the two spaces before "local" will be preserved when passed to the
connector processing (though in this case it won't matter because the
connector processing will ignore the extra spaces).

If you need a significant space, say in a filename passed to a key,
You cannot do:
.IP
accepter: ssl(CA=/etc/ser2net/my CA/),tcp,3000
.PP
because the accepter processing will split the arguments at the space
and won't recognize what "CA/" is.  You also cannot do:
.IP
accepter: ssl(CA="/etc/ser2net/my CA/"),tcp,3000
.PP
because YAML will remove the quotes, this is functionally equivalent to
the previous example. And
.IP
accepter: ssl(CA="/etc/ser2net/my\e CA/"),tcp,3000
.PP
also will not work, inside of double quotes YAML will convert "\e "
to a space.  You have a couple of options.  You can do:
.IP
accepter: ssl(CA=/etc/ser2net/my\e CA/),tcp,3000
.PP
or
.IP
accepter: ssl(CA='/etc/ser2net/my\e CA/'),tcp,3000
.PP
because outside of quotes YAML will not process the "\e " and it will
not process it in single quotes.  Or if you have a lot of spaces or
colons, too, you can do:
.IP
accepter: ssl(CA="\e"/etc/ser2net/my CA/\e""),tcp,3000
.PP
because inside the outside quotes YAML will convert the '\e"' into a '"'
and pass it on to the accepter processing which will interpret
the quotes as you would expect.

.SH UDP
UDP handling is a bit different than you might imagine, because it's
hard for ser2net to know where to send the data to.  To handle this,
UDP ports still have the concept of a "connection".  If a UDP port is
not connected, then if it receives a packet the remote address for
that packet is set to the remote end of the "connection".  It will do
all the normal new connection operations.  ser2net will accept new
connections up to "max-connections" then ignore packets from other
addresses until a disconnect occurs.

Unfortunately, there is no easy way to know when to disconnect.  You
have two basic options:
.IP \(bu
Set a timeout, if the remote end isn't heard from before the
timeout, then the port is disconnected and something else can
connect.  This means anything that is using the port must
periodically send a packet (empty is fine) to ser2net to
keep the connection alive.
.IP \(bu
Use the kickolduser option on the port, any new connection that
comes in will replace the previous connection.
.PP
Note that UDP ports handle multiple connections just like TCP ports,
so you can have multiple UDP listeners.

You also have a third option.  If you set a remote address (remaddr)
with a non-zero port and a connect back port (see discussion on remote
addresses above), ser2net will take one of the connections and assign
it to that port permanently.  This is called a fixed remote address.
All the traffic from the device will go to that port.  Every fixed
remote address on a UDP port has to have a corresponding connection,
so if you have 3 fixed remote addresses, you must have at least 3
connections.

.SH MULTIPLE CONNECTIONS
As mentioned earlier, you can set
.I max-connections=<n>
on a port to allow more than one connection at a time to the same serial
port.  These connections will share all the settings.  You cannot have
two separate TCP ports connect to the same port at the same time.

This has some significant interactions with other features:

.I flow control
is not exactly a feature, but more an interaction between the different
connections.  If a TCP port stops receiving data from ser2net, all TCP
ports connected will be flow-controlled.  This means a single TCP
connection can stop all the others.

.I closeon
will close all connections when the closeon sequence is seen.

.I openstr
is only sent when the port is unconnected and the first connections is
made.

.I closestr
is only sent when the last port disconnects and there are no more connections
to the port.

Any monitor ("monitor start" from a control connections) will catch
input from all network connections.

.I kickolduser
will kick off all connections if a connection comes in on a port that already
has a maximum number of connections.

.I tracing
will trace data from all network connections.

.I rfc2217
(remote telnet serial control) will change the connection settings on the
device and will be accepted from any network connection.

.I reconfig on SIGHUP
See ser2net(8) "SIGHUP" section for details.

.I ROTATOR
will only choose a port if there are no connections at all on the
port.  Note that the use of a rotator with a port with max-connections
> 1 will result in undefined behavior.

.I timeout
will be per TCP port and will only disconnect that TCP port on a timeout.

.I telnet_brk_on_sync
will send a break for any TCP port that does a sync.

.I showport
in the admin interface will show all possible connections, so if you say
.I max-connections=3
you will get three entries.

.I showshortport
in the admin interface will only show the first live connection, or if
no connection is present it will show whatever the first one was the
last time a connection was present.

.SH "AUTHENTICATION AND ENCRYPTION"

.SS "TCP WRAPPERS"
ser2net uses the tcp wrappers interface to implement host-based security.
See hosts_access(5) for a description of the file setup.  Two daemons are
used by ser2net, "ser2net" is for the data ports and "ser2net-control"
is for the control ports.

.SS "ENCRYPTION"
ser2net supports SSL encryption using the ssl gensio.  To enable
encryption, use an accepter like:
.IP
telnet,ssl,tcp,1234
.PP
Then you can use gensiot to connect:
.IP
gensiot telnet,ssl,<server>,1234
.PP
or you can install telnet-ssl and do
.IP
telnet -z ssl,secure <server> 1234
.PP
The SSL connection is made using the provided keys.  In this example
ser2net uses the default keys (as set in the default, see those
below).  You can also set them using (key=<keyfile>,cert=<certfile>)
after ssl above, or modify the defaults.

If you do not have genuine certificates from a certificate authority,
the connection will fail due to certificate failure.  Getting
certificates this way is very inconvenient, so there is another way.
You can do:
.IP
gtlssh-keygen --keydir /etc/ser2net --commonname "`hostname`-ser2net" serverkey ser2net
.PP
to generate the default keys in /etc/ser2net (or wherever).  The
certificate/key will be named /etc/ser2net/ser2net.crt|key.

.B NOTE:
If you compile ser2net yourself, by default autoconf sets the system
configuration directory (normally /etc) as /usr/etc.  This is a major
annoyance with autoconf.  So if you don't change it, you would need
/usr/etc above where it says /etc.  However, generally the right way to
do this is to add "--sysconfdir=/etc" to the configure command line
when you configure ser2net.  If a distro has compiled ser2net for you,
that should have done that by default, so no worries in that case.

Then copy ser2net.crt over to the user system and provide it to connection
commands, like:
.IP
gensiot telnet,ssl(CA=ser2net.crt),<server>,1234
.PP
or
.IP
telnet -z ssl,secure,cacert=ser2net.crt 1234
.PP
Then you will have an encrypted connection.  Just make sure your
certificates are valid.
.PP
Note that the "-ser2net" at the end of the key is important because it
make the subject name of the certificate more unique.  You can really
put anything you want for what you provide to keygen, as long as you
rename it properly.  That will be the subject name of the certificate.
.SS "AUTHENTICATION WITH SSL"
ser2net provides a way to authenticate with SSL.  It's not the
greatest, but it does work.  You must enable clientauth on ssl:
.IP
telnet,ssl(clientauth),tcp,1234
.PP
or set it in the default.  Then you must create a certificate
with the username as the common name.  You can do this with:
.IP
gtlssh-keygen --keydir outdir --commonname username keygen keyname
.PP
which will generate keyname.crt and keyname.key in outdir.  Then
put keyname.crt in ser2net's <authdir>/username/allowed_certs.  By
default <authdir> is /usr/share/ser2net/auth, but you can change
that with the authdir default in the ser2net config file or by
setting authdir on individual connections (in case you want differet
ones for different ports).  You then must rehash the allowed_certs
directory:
.IP
gtlssh-keygen rehash <authdir>/username/allowed_certs
.PP
Then restart/reload ser2net and use one of these very long lines to telnet
into it:
.IP
gensiot telnet,ssl(CA=ser2net.crt,cert=username.crt,key=username.key),<server>,1234

telnet -z ssl,secure,cacert=ser2net.crt,cert=username.crt,key=username.key server 1234
.PP
.SS "AUTHENTICATION WITH CERTAUTH (GTLSSH)"
All of the above is a big pain.  Fortunately there is an easier way.
gtlssh is a ssh-like program, but runs over TLS and it implements a
ssh-like authentication protocol using the certauth gensio.

ser2net supports this authentication system running on top of the
ssl and certauth gensios.  Those gensios provide the framework
for handling authentication, ser2net itself controls it.

This uses the same authdir and allowed keys directory as before,
and still requires a server certificate, but the self-signed one
generated with gtlssh-keygen works fine without doing anything
special.  Add certauth to the port line:
.IP
telnet,mux,certauth,ssl,tcp,1234
.PP
and *make sure* clientauth is disabled for ssl (or ssl will still
attempt to authenticate the client).  Disabled is the default but
in case you changed, the default...

The mux entry is because gtlssh uses the mux gensio to allow multiple
channels on the same session.  It wasn't there with older (pre 1.2)
version of gtlssh, but is required for newer one.  gtlssh also has a
.B --nomux
option, just in case.

The gtlssh program does its own certificate handling.  Look at the
gtlssh man page for detail on that.  Take the certificate for gtlssh
and put it in the authdir/username/allowed_certs directory and reshash
it as before.  gtlssh will *not* use the common name provided in the
certificate, instead it users a username provided by gtlssh.  Then
connect with gtlssh:
.IP
gtlssh --nosctp --telnet username@server 1234
.PP
The --nosctp thing keep gtlssh from trying sctp, which will fail
because we put tcp in the port line.  You could use sctp there and
get all its advantages for free!  Then --nosctp would no longer
be required to avoid the nagging.

The username is optional if it's the same as your current user.
If you have not connected to that server/port before, gtlssh will
ask you to verify it, much like ssh does.  If certificates, IP
address, etc. change, gtlssh will tell you about it.

If you do not want to use a certificate (certificates are certainly
preferred, but may not alway be workable) you can use a password
login, too.  Put a password in authdir/username/password.  When
you connect with gtlssh, if certificate validate fails, you will
be prompted for the password.  If it matches the first line in the
password file, then authentication will succeed.  You must set
enable-password in the certauth gensio options for passwords
to work.
.SS "AUTHENTICATION AND ROTATORS"
Rotators are a special case.  BE CAREFUL.  A rotator has its own
authentication.  If you set up authentication on a port that is
part of a rotator, that port's authentication is not used.  Only
the rotator's authentication is used.
.SS "ENCRYPTION, AUTHENTICATION, AND DEFAULT CERTIFICATES"
.B ser2net
expects default certificates and public keys in /etc/ser2net, and
these are set as gensio defaults.  This means that any outgoing
connection from ser2net, whether in a connector or in a connback, will
use these keys.  If they aren't there or have expired or something you
will get confusing errors about not being able to open the
certificates.

To solve this, you can disable the certificates by adding "cert=" to
the gensio specification for ssl and certauth on outgoing connections.
This will disable the certificates for the specific gensio, and is
probably what you want.  If you are making connections and
authenticating to the remote server, the default certificate and
private key are probably not what you want, either.
.SH "SIGNALS"
.TP 0.5i
.B SIGHUP
If ser2net receives a SIGHUP, it will reread it configuration file
and make the appropriate changes.  If an inuse port is changed or deleted,
the actual change will not occur until the port is disconnected.

.SH "ERRORS"
Almost all error output goes to syslog, not standard output.

.SH "FILES"
/etc/ser2net/ser2net.yaml, /etc/ser2net/ser2net.key,
/etc/ser2net/ser2net.crt, /usr/share/ser2net

.SH "SEE ALSO"
ser2net(8) telnet(1), hosts_access(5), gensio(5), gtlssh(1), gtlssh-keygen(1)

.SH "KNOWN PROBLEMS"
If they were known, they would be fixed :).

.SH AUTHOR
.PP
Corey Minyard <minyard@acm.org>
